package dbcon

import (
	"encoding/json"
	"fmt"
	"net/http"
	"night-talk/model"
	"strings"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/jinzhu/gorm"
)

// type Room struct {
// 	ID     uint
// 	Audios string
// 	Users  string
// 	num    uint
// }

func stringscontain(users string, username string) bool {
	arr := strings.Split(users, " ")

	for _, item := range arr {
		if item == username {
			return true
		}
	}
	return false

}

//DBpostRoomJoin is about user join room
func DBpostRoomJoin(c *gin.Context, db *gorm.DB) {
	username := c.PostForm("username")

	//u1 := model.User{Name: username}

	var users []model.User
	res := db.Where("name = ?", username).Find(&users)
	if res.RowsAffected == 0 {
		c.JSON(http.StatusBadRequest, gin.H{
			"msg": "用户不存在",
		})
		c.Abort()

	} else {
		var rooms []model.Room

		ress := db.Find(&rooms)

		for _, item := range rooms {
			//print(item.Users, " ", username)
			if stringscontain(item.Users, username) {

				c.JSON(http.StatusBadRequest, gin.H{
					"msg":    "用户已经在房间",
					"roomid": item.ID,
				})
				c.Abort()
				return
			}
		}
		ress = db.Where("num < 5").Find(&rooms)

		if ress.RowsAffected == 0 {
			db.Save(&model.Room{
				Audios: "", Users: username, Num: 1, Recordtimes: ";",
			})

			var roomss []model.Room
			db.Where("num = 1").Find(&roomss)

			for _, item := range roomss {
				if stringscontain(item.Users, username) {
					c.JSON(http.StatusOK, gin.H{
						"msg":    "success",
						"roomid": item.ID,
					})
					break
				}
			}

		} else {

			roomm := rooms[0]
			roomm.Num++
			roomm.Users += " " + username
			roomm.Recordtimes += ";"
			db.Save(&roomm)
			c.JSON(http.StatusOK, gin.H{
				"msg":    "success",
				"roomid": roomm.ID,
			})

		}

	}
}

// DBgetRoomIsFull is to check whether the room is full
func DBgetRoomIsFull(c *gin.Context, db *gorm.DB) {
	roomid := c.Param("roomid")

	var roomm model.Room

	res := db.Where("id = ?", roomid).Find(&roomm)

	if res.RowsAffected == 0 {
		c.JSON(http.StatusBadRequest, gin.H{
			"msg": "Room doesnt exist",
		})
		c.Abort()
	} else {
		var msg string
		if roomm.Num == 5 {
			msg = "full"
		} else {
			msg = "not full"
		}
		c.JSON(http.StatusOK, gin.H{
			"msg": msg,
		})
	}
}

func getindex(users string, username string) uint {

	userss := strings.Split(users, " ")

	for i, namee := range userss {
		if namee == username {
			return uint(i)
		}
	}
	if !stringscontain(users, username) {
		return uint(len(userss))
	} else {
		return 0
	}
}

func gettime(recordtimes string, users string, username string) string {
	index := getindex(users, username)

	records := strings.Split(recordtimes, ";")

	return records[index]
}

func settime(recordtimes string, record string, users string, username string) string {
	index := getindex(users, username)

	records := strings.Split(recordtimes, ";")
	records[index] = record

	return strings.Join(records, ";")
}

//DBpostRoomUserCancel is to cancel room join
func DBpostRoomUserCancel(c *gin.Context, db *gorm.DB) {
	roomid := c.PostForm("roomid")
	username := c.PostForm("username")
	var roomm model.Room
	var userr model.User

	res := db.Where("id = ?", roomid).Find(&roomm)
	ress := db.Where("name = ?", username).Find(&userr)

	if res.RowsAffected == 0 {
		c.JSON(http.StatusBadRequest, gin.H{
			"msg": "Room doesnt exist",
		})
		c.Abort()
	} else {
		if ress.RowsAffected == 0 {
			c.JSON(http.StatusBadRequest, gin.H{
				"msg": "User doesnt exist",
			})
			c.Abort()
		} else {
			if stringscontain(roomm.Users, username) {
				if roomm.Num == 1 {
					db.Delete(&roomm)
				} else {

					indexx := getindex(roomm.Users, username)

					print(indexx)

					records := strings.Split(roomm.Recordtimes, ";")
					records = append(records[:indexx], records[indexx+1:]...)

					roomm.Recordtimes = strings.Join(records, ";")

					usersss := strings.Split(roomm.Users, " ")
					usersss = append(usersss[:indexx], usersss[indexx+1:]...)

					roomm.Users = strings.Join(usersss, " ")
					roomm.Num--

					db.Save(&roomm)

				}
				c.JSON(http.StatusOK, gin.H{
					"msg": "success",
				})
			} else {
				c.JSON(http.StatusBadRequest, gin.H{
					"msg": username + " is not in room " + roomid,
				})
				c.Abort()
			}
		}
	}
}

// DBgetRoomAudios is to get all audios belonging to specific room
func DBgetRoomAudios(c *gin.Context, db *gorm.DB) {
	roomid := c.Param("roomid")

	// res := db.Model(&model.Room{}).Create(map[string]interface{}{
	// 	"Audios": "temp.wav", "Users": "hello", "num": 0,
	// })

	var roomm model.Room

	res := db.Where("id = ?", roomid).Find(&roomm)

	if res.RowsAffected == 0 {
		c.JSON(http.StatusBadRequest, gin.H{
			"msg": "Room doesnt exist",
		})
		c.Abort()
	} else {
		arr := strings.Split(roomm.Audios, " ")
		fmt.Println(len(arr))
		result, _ := json.Marshal(arr)
		c.JSON(http.StatusOK, gin.H{
			"msg": string(result),
		})
	}
}

//DBpostForRoomUserAudio is to get user Audio
func DBpostForRoomUserAudio(c *gin.Context, db *gorm.DB) {
	roomid := c.PostForm("roomid")
	username := c.PostForm("username")
	var roomm model.Room
	var userr model.User
	var audios []model.Audio

	res := db.Where("id = ?", roomid).Find(&roomm)
	ress := db.Where("name = ?", username).Find(&userr)

	if res.RowsAffected == 0 {
		c.JSON(http.StatusBadRequest, gin.H{
			"msg": "Room doesnt exist",
		})
		c.Abort()
	} else {
		if ress.RowsAffected == 0 {
			c.JSON(http.StatusBadRequest, gin.H{
				"msg": "User doesnt exist",
			})
			c.Abort()
		} else {
			if stringscontain(roomm.Users, username) {

				timee := gettime(roomm.Recordtimes, roomm.Users, username)

				now := time.Now()

				db.Find(&audios)
				if timee == "" {
					var audiosStr []string

					for _, val := range audios {
						audiosStr = append(audiosStr, val.Data)
					}
					roomm.Recordtimes = settime(roomm.Recordtimes, now.Format("2006-01-02 15:04:05"), roomm.Users, username)

					db.Save(&roomm)
					c.JSON(http.StatusOK, gin.H{
						"msg": audiosStr,
					})

				} else {
					var audiosStr []string
					loc := time.Local
					st, _ := time.ParseInLocation("2006-01-02 15:04:05", timee, loc)
					for _, val := range audios {
						valcrea := val.CreatedAt

						if valcrea.After(st) {
							audiosStr = append(audiosStr, val.Data)
						}

					}
					roomm.Recordtimes = settime(roomm.Recordtimes, now.Format("2006-01-02 15:04:05"), roomm.Users, username)

					db.Save(&roomm)
					c.JSON(http.StatusOK, gin.H{
						"msg": audiosStr,
					})
				}

			} else {
				c.JSON(http.StatusBadRequest, gin.H{
					"msg": username + " is not in room " + roomid,
				})
				c.Abort()
			}
		}
	}
}
